<?php
namespace  app\common\service\token\driver;

use aes\Aes;
use app\common\service\ServiceBase;
use app\common\service\token\TokenInterface;
use Firebase\JWT\JWT;
use think\facade\Cache;
use think\facade\Request;

/**
 * 第三方应用的临时授权，使用授权码模式
 */
class OauthToken implements TokenInterface{

    use ServiceBase;


    /**
     * 第三方token解码
     * @param $param
     * @return mixed
     */
    public function getAccessTokenInfo($param){
//        $param['access_token'] = Request::header('Access-Token');
        (empty($param['access_token']) || empty($param['uid']) )&& ServiceBase::commonError(['code'=>500,'msg'=>'参数不能为空',"success"=>false]);
        $key = API_KEY . JWT_KEY;
        $jwt_arr[] = JWT::urlsafeB64Encode(json_encode(['typ' => 'JWT', 'alg' => 'HS256']));
        $jwt_arr[] = Cache::get($param['uid'] . "_" . $param['access_token']);
        empty($jwt_arr[1]) && ServiceBase::commonError(['code'=>500,'msg'=>'token过期',"success"=>false]);
        $jwt_arr[] = Aes::strDecrypt(urldecode($param['access_token']));
        $jwt_string = implode('.', $jwt_arr);
        $info = JWT::decode($jwt_string, $key, ['HS256']);
        time() >= $info->exp && Cache::delete($param['uid'] . "_" . $param['access_token']) && ServiceBase::commonError(['code'=>500,'msg'=>'token过期',"success"=>false]);
        return $info->data;

    }

    /**
     * 第三方生成token
     * @param $param
     * @return array[]
     */
    public function createAccessToken($param){

        (empty($param['app_id']) || empty($param['redirect_uri']) || empty($param['code'])) && ServiceBase::commonError(['code'=>500,'msg'=>'请求不合法',"success"=>false]);

        $data['appid'] = $param['app_id'];
        $data['redirect_url'] = $param['redirect_uri'];
        $data['code'] = $param['code'];

        $cache_app = Cache::get($data['appid'].'_'.$data['redirect_url']);
        (empty($cache_app) || $cache_app['code']!= $data['code'])&& ServiceBase::commonError(['code'=>500,'msg'=>'授权码错误',"success"=>false]);
        $where['member_id'] = $cache_app['member_id'];
        $user_info = self::model('Member')->getMemberInfo($where);
        empty($user_info) && ServiceBase::commonError(['code'=>500,'msg'=>'用户不存在',"success"=>false]);

        $info['nickName'] = $user_info['nickname'];
        $info['memberAvatar'] = $user_info['member_avatar'];
        $info['memberSex'] = $user_info['member_sex'];
        $info['memberBirthday'] = $user_info['member_birthday'];
        $info['email'] = $user_info['email'];

        $uid = substr(md5( $where['member_id']), 8, 16);
        $key = API_KEY . JWT_KEY;
        $merchant_token = [
            "iss"  => "yiqiai",                 // 签发者
            "iat"  => TIME_NOW,                 // 签发时间
            "exp"  => TIME_NOW + 8000,          // 过期时间
            "aud"  =>$uid,        // 接收方
            "sub"  => $uid,        // 面向的用户
            "data" => $info
        ];

        $jwt_string = JWT::encode($merchant_token, $key);
        $token_array = explode('.', $jwt_string);
        $user_token = urlencode(Aes::strEncrypt(end($token_array)));
        Cache::set($uid . "_" . $user_token, $token_array[1], 8000);
        unset($info['allow_link']);
        return ['data' => ['access_token' => $user_token, 'uid' => $uid]];

    }

    /**
     * 第三方授权码生成
     * @param $param
     * @return string
     */
    public function getOauthCode($param){

        (empty($param['app_id']) || empty($param['redirect_uri']) || empty($param['member_id'])) && ServiceBase::commonError(['code'=>500,'msg'=>'请求不合法',"success"=>false]);
        $where['appid'] = $param['app_id'];
        $where['redirect_url'] = $param['redirect_uri'];
        $info = self::model('PartnerApp')->getPartnerAppInfo($where);
        empty($info) && ServiceBase::commonError(['code'=>500,'msg'=>'参数错误',"success"=>false]);

        $code = CreateOauthCode($where);
        $where['code'] = $code;
        $where['member_id'] = $param['member_id'];
        Cache::set( $where['appid'].'_'.$where['redirect_url'],$where,300);
        return $param['redirect_uri']."?code=".$code;

    }
}